# -*- coding: UTF-8 -*-
#! /usr/bin/env python
## 连接配置
from db import conn_config
from utils.redis_client import (
    get_redis_connection,
    hash_set,
    hash_get,
    hash_getall,
    delete_key,
    set_value
)
from utils.logger import get_logger
import pymysql
import datetime

# 创建日志器
logger = get_logger("sleep_redis", daily_rotation=True)

def SC_SetSleepData2Redis(mac, recv, time):
    """
    将收到的每条数据存进redis中
    :param mac: 设备MAC地址
    :param recv: 接收到的数据数组
    :param time: 超时时间
    """
    try:
        # 转为字符串存储
        strarr = ','.join(str(i) for i in recv)
        key = "sc-sleepdata-" + mac
        
        # 使用hash_set设置数据
        hash_set(key, recv[0], strarr)
        
        # 设置过期时间
        redis = get_redis_connection()
        redis.expire(key, time)
        
        logger.debug(f"成功设置睡眠数据到Redis: {key}, field: {recv[0]}")
    except Exception as e:
        logger.error(f"设置睡眠数据到Redis失败: {str(e)}", exc_info=True)
        raise

def SC_CheckAndSetRedisData2Mysql(mac, check_len):
    """
    检查数据长度，如果达到指定长度则写入MySQL
    :param mac: 设备MAC地址
    :param check_len: 检查的数据长度
    """
    try:
        key = "sc-sleepdata-" + mac
        redis = get_redis_connection()
        
        now_len = redis.hlen(key)
        if check_len > now_len:
            return

        # 获取所有数据
        data = hash_getall(key)
        data_row = []
        
        for value in data.values():
            row = value.split(',')
            if len(row) == 21:
                # 老版数据补25个0
                row.extend([0] * 25)
            data_row.append(row)
            
        # 删除Redis中的数据
        delete_key(key)

        # 使用参数化查询
        sql = """
            INSERT IGNORE INTO `{table}` 
            (TM, HR, RR, SV, HRV, SS, Status, B2B, B2B1, B2B2, TEMP, SP, DP, RTT, HTT, TTT, LTT, TRMAX, TRMIN, TFM, LHK, LKN, LIK, LKL, LIJ, LJK, LHJHN, LKNHN, LHJKN, LHI, LHJ, LHM, LMN, LLM, PKL, PJKPJ, PIK, PMN, PLMLM, SHKHN, SKNHN, SIKMN, EKN, EHKHN, EKNHN, EHKKN) 
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
        """.format(table=mac)

        # 操作数据库
        db = pymysql.connect(**conn_config)
        cursor = db.cursor()
        cursor.executemany(sql, data_row)
        db.commit()
        cursor.close()
        db.close()
        
        logger.info(f"成功将数据同步到MySQL: {mac}, 数据条数: {len(data_row)}")
    except Exception as e:
        logger.error(f"数据同步到MySQL失败: {str(e)}", exc_info=True)
        raise

def SC_GetNowTimeSleepDataByMac(mac):
    """
    获取当前时间的睡眠数据
    :param mac: 设备MAC地址
    :return: 数据数组
    """
    try:
        key = "sc-sleepdata-" + mac
        
        current = datetime.datetime.now()
        deltat = datetime.timedelta(seconds=5)  # 查询5s以前的数据
        now_time = current - deltat
        field = now_time.strftime('%Y-%m-%d %H:%M:%S')

        str_row = hash_get(key, field)
        if str_row is None:
            return []

        arr_row = str_row.split(',')
        logger.debug(f"成功获取睡眠数据: {mac}, 时间: {field}")
        return arr_row
    except Exception as e:
        logger.error(f"获取睡眠数据失败: {str(e)}", exc_info=True)
        return []

def update_device_heartbeat(mac):
    """
    更新设备心跳时间
    :param mac: 设备MAC地址
    """
    try:
        key = f"sc-device-status:{mac}"
        # 设置键值并保留300秒（5分钟）
        set_value(key, datetime.datetime.now().isoformat(), ex=300)
        logger.debug(f"成功更新设备心跳: {mac}")
    except Exception as e:
        logger.error(f"更新设备心跳失败: {str(e)}", exc_info=True)
        raise

def get_online_devices():
    """
    获取当前在线设备列表
    :return: 在线MAC地址列表
    """
    try:
        redis = get_redis_connection()
        # 使用SCAN代替KEYS避免阻塞问题
        online_keys = []
        cursor = '0'
        while cursor != 0:
            cursor, partial_keys = redis.scan(cursor, match="sc-device-status:*")
            online_keys.extend(partial_keys)
        # 提取MAC地址（去掉前缀）
        devices = [key.split(":")[1] for key in online_keys]
        logger.debug(f"成功获取在线设备列表，数量: {len(devices)}")
        return devices
    except Exception as e:
        logger.error(f"获取在线设备列表失败: {str(e)}", exc_info=True)
        return []